Täiusta Express.js rakendusi TypeScripti tüübiohutusega. Juhend käsitleb marsruudikäitlejaid, vahevara tüüpe ja parimaid tavasid skaleeritavate API-de loomiseks.
TypeScripti ja Expressi integreerimine: marsruudikäitleja tüübiohutus
TypeScriptist on saanud kaasaegse JavaScripti arenduse nurgakivi, pakkudes staatilise tüübi võimalusi, mis parandavad koodi kvaliteeti, hooldatavust ja skaleeritavust. Koos Express.js-iga, mis on populaarne Node.js-i veebirakenduste raamistik, saab TypeScript oluliselt parandada teie taustarakenduste API-de tugevust. See põhjalik juhend uurib, kuidas kasutada TypeScripti marsruudikäitleja tüübiohutuse saavutamiseks Express.js rakendustes, pakkudes praktilisi näiteid ja parimaid tavasid tugevate ja hooldatavate API-de loomiseks globaalsele publikule.
Miks on tüübiohutus Express.js-is oluline
Dünaamilistes keeltes nagu JavaScript tabatakse vead sageli käitusajal, mis võib viia ootamatu käitumise ja raskesti silmaviivavate probleemideni. TypeScript lahendab selle staatilise tüüpimisega, võimaldades teil vigu tabada arenduse ajal, enne kui need tootmisse jõuavad. Express.js-i kontekstis on tüübiohutus eriti oluline marsruudikäitlejate puhul, kus tegelete päringu- ja vastuseobjektide, päringuparameetrite ja päringukeredega. Nende elementide vale käitlemine võib viia rakenduse kokkujooksmiseni, andmete riknemiseni ja turvanõrkusteni.
- Varajane veadetektsioon: Tabage tüübivigad arenduse ajal, vähendades käitusaja üllatuste tõenäosust.
- Parem koodi hooldatavus: Tüübi annotatsioonid muudavad koodi lihtsamini mõistetavaks ja refaktoreeritavaks.
- Täiustatud koodi automaatne täitmine ja tööriistad: IDE-d saavad pakkuda paremaid soovitusi ja veakontrolli tüübiinfoga.
- Vähem vigu: Tüübiohutus aitab vältida levinud programmeerimisvigu, näiteks valede andmetüüpide edastamist funktsioonidele.
TypeScripti Express.js projekti seadistamine
Enne marsruudikäitleja tüübiohutuse juurde asumist seadistame põhilise TypeScripti Express.js projekti. See on meie näidete aluseks.
Eeltingimused
- Paigaldatud Node.js ja npm (Node Package Manager). Saate need alla laadida Node.js-i ametlikult veebisaidilt. Optimaalse ühilduvuse tagamiseks veenduge, et teil on hiljutine versioon.
- Koodiredaktor nagu Visual Studio Code, mis pakub suurepärast TypeScripti tuge.
Projekti initsialiseerimine
- Loo uus projekti kataloog:
mkdir typescript-express-app && cd typescript-express-app - Initsialiseeri uus npm projekt:
npm init -y - Installi TypeScript ja Express.js:
npm install typescript express - Installi Express.js-i TypeScripti deklaratsioonifailid (oluline tüübiohutuse jaoks):
npm install @types/express @types/node - Initsialiseeri TypeScript:
npx tsc --init(See loobtsconfig.jsonfaili, mis konfigureerib TypeScripti kompilaatori.)
TypeScripti konfigureerimine
Ava tsconfig.json fail ja konfigureeri see vastavalt. Siin on näidiskonfiguratsioon:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
Olulised konfiguratsioonid:
target: Määrab ECMAScripti sihtversiooni.es6on hea alguspunkt.module: Määrab mooduli koodi genereerimise.commonjson Node.js-i jaoks tavaline valik.outDir: Määrab kompileeritud JavaScripti failide väljundkataloogi.rootDir: Määrab teie TypeScripti lähtefailide juurkataloogi.strict: Lubab kõik ranged tüübikontrolli valikud täiustatud tüübiohutuse jaoks. See on tungivalt soovitatav.esModuleInterop: Lubab ühilduvuse CommonJS ja ES moodulite vahel.
Sisenemispunkti loomine
Loo src kataloog ja lisa index.ts fail:
mkdir src
touch src/index.ts
Täida src/index.ts põhilise Express.js serveri seadistusega:
import express, { Request, Response } from 'express';
const app = express();
const port = 3000;
app.get('/', (req: Request, res: Response) => {
res.send('Tere, TypeScript Express!');
});
app.listen(port, () => {
console.log(`Server töötab aadressil http://localhost:${port}`);
});
Kompileerimisskripti lisamine
Lisa kompileerimisskript oma package.json faili, et kompileerida TypeScripti kood:
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"dev": "npm run build && npm run start"
}
Nüüd saate käivitada npm run dev, et ehitada ja käivitada server.
Marsruudikäitleja tüübiohutus: päringu- ja vastusetüüpide määratlemine
Marsruudikäitleja tüübiohutuse tuum seisneb Request ja Response objektide tüüpide õiges määratlemises. Express.js pakub nende objektide jaoks üldisi tüüpe, mis võimaldavad teil määrata päringuparameetrite, päringukerede ja marsruudiparameetrite tüüpe.
Põhilised marsruudikäitleja tüübid
Alustame lihtsa marsruudikäitlejaga, mis ootab nime päringuparameetrina:
import express, { Request, Response } from 'express';
const app = express();
const port = 3000;
interface NameQuery {
name: string;
}
app.get('/hello', (req: Request, res: Response) => {
const name = req.query.name;
if (!name) {
return res.status(400).send('Nime parameeter on kohustuslik.');
}
res.send(`Tere, ${name}!`);
});
app.listen(port, () => {
console.log(`Server töötab aadressil http://localhost:${port}`);
});
Selles näites:
Request<any, any, any, NameQuery>määratleb päringuobjekti tüübi.- Esimene
anyesindab marsruudiparameetreid (nt/users/:id). - Teine
anyesindab vastusekere tüüpi. - Kolmas
anyesindab päringukere tüüpi. NameQueryon liides, mis määratleb päringuparameetrite struktuuri.
Määratledes NameQuery liidese, saab TypeScript nüüd kontrollida, kas req.query.name omadus eksisteerib ja on tüüpi string. Kui proovite ligi pääseda olematule omadusele või määrata väärtuse vale tüübiga, annab TypeScript vea.
Päringukerede käsitlemine
Marsruutide puhul, mis aktsepteerivad päringukeresid (nt POST, PUT, PATCH), saate määratleda päringukerele liidese ja kasutada seda Request tüübis:
import express, { Request, Response } from 'express';
import bodyParser from 'body-parser';
const app = express();
const port = 3000;
app.use(bodyParser.json()); // Oluline JSON-päringukerede parsimiseks
interface CreateUserRequest {
firstName: string;
lastName: string;
email: string;
}
app.post('/users', (req: Request, res: Response) => {
const { firstName, lastName, email } = req.body;
// Kontrolli päringukere
if (!firstName || !lastName || !email) {
return res.status(400).send('Puuduvad kohustuslikud väljad.');
}
// Töötle kasutaja loomist (nt salvesta andmebaasi)
console.log(`Kasutaja loomine: ${firstName} ${lastName} (${email})`);
res.status(201).send('Kasutaja loodud edukalt.');
});
app.listen(port, () => {
console.log(`Server töötab aadressil http://localhost:${port}`);
});
Selles näites:
CreateUserRequestmääratleb eeldatava päringukere struktuuri.app.use(bodyParser.json())on ülioluline JSON-päringukerede parsimiseks. Ilma selleta onreq.bodymääratlemata.Requesttüüp on nüüdRequest<any, any, CreateUserRequest>, mis näitab, et päringukere peab vastamaCreateUserRequestliidesele.
TypeScript tagab nüüd, et req.body objekt sisaldab eeldatavaid omadusi (firstName, lastName ja email) ja et nende tüübid on õiged. See vähendab oluliselt käitusaja vigade riski, mis on põhjustatud valedest päringukere andmetest.
Marsruudiparameetrite käsitlemine
Marsruutide puhul, millel on parameetrid (nt /users/:id), saate määratleda marsruudiparameetritele liidese ja kasutada seda Request tüübis:
import express, { Request, Response } from 'express';
const app = express();
const port = 3000;
interface UserParams {
id: string;
}
interface User {
id: string;
firstName: string;
lastName: string;
email: string;
}
const users: User[] = [
{ id: '1', firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com' },
{ id: '2', firstName: 'Jane', lastName: 'Smith', email: 'jane.smith@example.com' },
];
app.get('/users/:id', (req: Request, res: Response) => {
const userId = req.params.id;
const user = users.find(u => u.id === userId);
if (!user) {
return res.status(404).send('Kasutajat ei leitud.');
}
res.json(user);
});
app.listen(port, () => {
console.log(`Server töötab aadressil http://localhost:${port}`);
});
Selles näites:
UserParamsmääratleb marsruudiparameetrite struktuuri, täpsustades, etidparameeter peaks olema string.Requesttüüp on nüüdRequest<UserParams>, mis näitab, etreq.paramsobjekt peaks vastamaUserParamsliidesele.
TypeScript tagab nüüd, et req.params.id omadus eksisteerib ja on tüüpi string. See aitab vältida vigu, mis on põhjustatud olematute marsruudiparameetritele ligipääsust või nende kasutamisest valede tüüpidega.
Vastusetüüpide määramine
Kuigi päringu tüübiohutusele keskendumine on ülioluline, parandab vastusetüüpide määratlemine ka koodi selgust ja aitab vältida ebakõlasid. Saate määratleda vastuses tagasi saadetava andmetüübi.
import express, { Request, Response } from 'express';
const app = express();
const port = 3000;
interface User {
id: string;
firstName: string;
lastName: string;
email: string;
}
const users: User[] = [
{ id: '1', firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com' },
{ id: '2', firstName: 'Jane', lastName: 'Smith', email: 'jane.smith@example.com' },
];
app.get('/users', (req: Request, res: Response) => {
res.json(users);
});
app.listen(port, () => {
console.log(`Server töötab aadressil http://localhost:${port}`);
});
Siin määrab Response<User[]>, et vastusekere peaks olema User objektide massiiv. See aitab tagada, et saadate API vastustes järjepidevalt õige andmestruktuuri. Kui proovite saata andmeid, mis ei vasta `User[]` tüübile, väljastab TypeScript hoiatuse.
Vahevara tüübiohutus
Vahevarafunktsioonid on Express.js rakendustes ristlõikeküsimuste käsitlemiseks hädavajalikud. Tüübiohutuse tagamine vahevaras on sama oluline kui marsruudikäitlejates.
Vahevarafunktsioonide tüüpimine
Vahevarafunktsiooni põhistruktuur TypeScriptis on sarnane marsruudikäitleja omaga:
import express, { Request, Response, NextFunction } from 'express';
function authenticationMiddleware(req: Request, res: Response, next: NextFunction) {
// Autentimisloogika
const isAuthenticated = true; // Asenda tegeliku autentimiskontrolliga
if (isAuthenticated) {
next(); // Jätka järgmise vahevara või marsruudikäitlejaga
} else {
res.status(401).send('Volitamata');
}
}
const app = express();
const port = 3000;
app.use(authenticationMiddleware);
app.get('/', (req: Request, res: Response) => {
res.send('Tere, autentitud kasutaja!');
});
app.listen(port, () => {
console.log(`Server töötab aadressil http://localhost:${port}`);
});
Selles näites:
NextFunctionon Express.js-i pakutav tüüp, mis esindab järgmist vahevarafunktsiooni ahelas.- Vahevarafunktsioon võtab samad
RequestjaResponseobjektid nagu marsruudikäitlejad.
Päringuobjekti laiendamine
Mõnikord võite soovida lisada oma vahevaras Request objektile kohandatud omadusi. Näiteks autentimisvahevara võib lisada päringuobjektile user omaduse. Selle tüübiohutu saavutamiseks peate laiendama Request liidest.
import express, { Request, Response, NextFunction } from 'express';
interface User {
id: string;
username: string;
email: string;
}
// Laienda Request liidest
declare global {
namespace Express {
interface Request {
user?: User;
}
}
}
function authenticationMiddleware(req: Request, res: Response, next: NextFunction) {
// Autentimisloogika (asenda tegeliku autentimiskontrolliga)
const user: User = { id: '123', username: 'johndoe', email: 'john.doe@example.com' };
req.user = user; // Lisa kasutaja päringuobjektile
next(); // Jätka järgmise vahevara või marsruudikäitlejaga
}
const app = express();
const port = 3000;
app.use(authenticationMiddleware);
app.get('/', (req: Request, res: Response) => {
const username = req.user?.username || 'Külaline';
res.send(`Tere, ${username}!`);
});
app.listen(port, () => {
console.log(`Server töötab aadressil http://localhost:${port}`);
});
Selles näites:
- Kasutame globaalset deklaratsiooni
Express.Requestliidese laiendamiseks. - Lisame
Requestliidesele valikuliseuseromaduse tüübigaUser. - Nüüd saate oma marsruudikäitlejates
req.useromadusele ligi pääseda, ilma et TypeScript kaebaks. `?` `req.user?.username` on ülioluline juhtudel, kus kasutaja pole autentitud, vältides võimalikke vigu.
Parimad tavad TypeScripti ja Expressi integreerimiseks
TypeScripti eeliste maksimeerimiseks oma Express.js rakendustes järgige neid parimaid tavasid:
- Luba striktne režiim: Kasuta oma
tsconfig.jsonfailis valikut"strict": true, et lubada kõik ranged tüübikontrolli valikud. See aitab tabada võimalikke vigu varakult ja tagab kõrgema tüübiohutuse taseme. - Kasuta liideseid ja tüübialiasi: Määratle liidesed ja tüübialiaase oma andmete struktuuri esindamiseks. See muudab teie koodi loetavamaks ja hooldatavamaks.
- Kasuta üldtüüpe: Kasuta üldtüüpe korduvkasutatavate ja tüübiohutute komponentide loomiseks.
- Kirjuta ühikteste: Kirjuta ühikteste oma koodi õigsuse kontrollimiseks ja veendumaks, et teie tüübi annotatsioonid on täpsed. Testimine on koodi kvaliteedi säilitamiseks ülioluline.
- Kasuta linterit ja formaatijat: Kasuta linterit (nagu ESLint) ja formaatijat (nagu Prettier), et tagada järjepidevad kodeerimisstiilid ja tabada võimalikke vigu.
- Väldi
anytüüpi: Minimeerianytüübi kasutamist, kuna see möödub tüübikontrollist ja nurjab TypeScripti kasutamise eesmärgi. Kasuta seda ainult siis, kui see on absoluutselt vajalik, ja kaalu võimalusel spetsiifilisemate tüüpide või üldtüüpide kasutamist. - Struktureeri oma projekt loogiliselt: Korralda oma projekt moodulitesse või kaustadesse funktsionaalsuse alusel. See parandab teie rakenduse hooldatavust ja skaleeritavust.
- Kasuta sõltuvussüstimist: Kaalu sõltuvussüstimise konteineri kasutamist oma rakenduse sõltuvuste haldamiseks. See võib muuta teie koodi testitavamaks ja hooldatavamaks. Teegid nagu InversifyJS on populaarsed valikud.
Täiustatud TypeScripti kontseptsioonid Express.js-i jaoks
Dekoraatorite kasutamine
Dekoraatorid pakuvad kompaktset ja väljendusrikast viisi metaandmete lisamiseks klassidele ja funktsioonidele. Saate kasutada dekoraatoreid marsruutide registreerimise lihtsustamiseks Express.js-is.
Esmalt peate oma tsconfig.json failis lubama eksperimentaalsed dekoraatorid, lisades compilerOptions alla "experimentalDecorators": true.
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"experimentalDecorators": true
}
}
Seejärel saate marsruutide registreerimiseks luua kohandatud dekoraatori:
import express, { Router, Request, Response } from 'express';
function route(method: string, path: string) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
if (!target.__router__) {
target.__router__ = Router();
}
target.__router__[method](path, descriptor.value);
};
}
class UserController {
@route('get', '/users')
getUsers(req: Request, res: Response) {
res.send('Kasutajate nimekiri');
}
@route('post', '/users')
createUser(req: Request, res: Response) {
res.status(201).send('Kasutaja loodud');
}
public getRouter() {
return this.__router__;
}
}
const userController = new UserController();
const app = express();
const port = 3000;
app.use('/', userController.getRouter());
app.listen(port, () => {
console.log(`Server töötab aadressil http://localhost:${port}`);
});
Selles näites:
routedekoraator võtab argumentidena HTTP meetodi ja tee.- See registreerib kaunistatud meetodi klassiga seotud marsruuteri marsruudikäitlejana.
- See lihtsustab marsruutide registreerimist ja muudab teie koodi loetavamaks.
Kohandatud tüübikaitsete kasutamine
Tüübikaitsed on funktsioonid, mis kitsendavad muutuja tüüpi kindlas ulatuses. Saate kasutada kohandatud tüübikaitseid päringukerede või päringuparameetrite valideerimiseks.
interface Product {
id: string;
name: string;
price: number;
}
function isProduct(obj: any): obj is Product {
return typeof obj === 'object' &&
obj !== null &&
typeof obj.id === 'string' &&
typeof obj.name === 'string' &&
typeof obj.price === 'number';
}
import express, { Request, Response } from 'express';
import bodyParser from 'body-parser';
const app = express();
const port = 3000;
app.use(bodyParser.json());
app.post('/products', (req: Request, res: Response) => {
if (!isProduct(req.body)) {
return res.status(400).send('Kehtetud tooteandmed');
}
const product: Product = req.body;
console.log(`Toote loomine: ${product.name}`);
res.status(201).send('Toode loodud');
});
app.listen(port, () => {
console.log(`Server töötab aadressil http://localhost:${port}`);
});
Selles näites:
isProductfunktsioon on kohandatud tüübikaitse, mis kontrollib, kas objekt vastabProductliidesele.- Marsruudikäitlejas
/productskasutatakseisProductfunktsiooni päringukere valideerimiseks. - Kui päringukere on kehtiv toode, teab TypeScript, et
req.bodyonProducttüüpiifploki sees.
Globaalsete kaalutluste käsitlemine API disainis
Globaalsele publikule API-de disainimisel tuleks arvesse võtta mitmeid tegureid, et tagada juurdepääsetavus, kasutatavus ja kultuuriline tundlikkus.
- Lokaliseerimine ja internationaliseerimine (i18n ja L10n):
- Sisu läbirääkimine: Toeta mitut keelt ja piirkonda sisu läbirääkimiste kaudu, mis põhinevad
Accept-Languagepäisel. - Kuupäeva ja kellaaja vormindamine: Kasuta ISO 8601 formaati kuupäevade ja kellaaegade esitamiseks, et vältida mitmetähenduslikkust erinevates piirkondades.
- Numbrite vormindamine: Käsitle numbrite vormindamist vastavalt kasutaja lokaadile (nt kümnendkohad ja tuhandeliste eraldajad).
- Valuuta käsitlemine: Toeta mitut valuutat ja paku vajadusel valuutakursside teavet.
- Teksti suund: Kohanda paremalt vasakule (RTL) keeltega nagu araabia ja heebrea keel.
- Sisu läbirääkimine: Toeta mitut keelt ja piirkonda sisu läbirääkimiste kaudu, mis põhinevad
- Ajavööndid:
- Salvesta kuupäevad ja kellaajad UTC (Coordinated Universal Time) formaadis serveri poolel.
- Luba kasutajatel määrata oma eelistatud ajavöönd ja teisendada kuupäevi ja kellaaegu vastavalt kliendipoolses rakenduses.
- Kasuta teeke nagu
moment-timezoneajavööndi teisenduste käsitlemiseks.
- Märgi kodeerimine:
- Kasuta UTF-8 kodeeringut kõikide tekstiliste andmete jaoks, et toetada laia valikut erinevate keelte märke.
- Veendu, et teie andmebaas ja muud andmesalvestussüsteemid on konfigureeritud kasutama UTF-8.
- Juurdepääsetavus:
- Järgi juurdepääsetavuse juhiseid (nt WCAG), et muuta teie API ligipääsetavaks puuetega kasutajatele.
- Esita selged ja kirjeldavad veateated, mis on kergesti mõistetavad.
- Kasuta oma API dokumentatsioonis semantilisi HTML-elemente ja ARIA atribuute.
- Kultuuriline tundlikkus:
- Väldi kultuurispetsiifiliste viidete, idioomide või huumori kasutamist, mis ei pruugi olla kõigile kasutajatele arusaadavad.
- Ole teadlik kultuurilistest erinevustest suhtlusstiilides ja eelistustes.
- Arvesta oma API potentsiaalset mõju erinevatele kultuurigruppidele ja väldi stereotüüpide või eelarvamuste edasiandmist.
- Andmekaitse ja turvalisus:
- Järgi andmekaitse regulatsioone, nagu GDPR (üldine andmekaitsemäärus) ja CCPA (California tarbija privaatsuse seadus).
- Rakenda tugevad autentimis- ja autoriseerimismehhanismid kasutajaandmete kaitsmiseks.
- Krüpteeri tundlikud andmed nii edastamisel kui ka puhkeseisundis.
- Paku kasutajatele kontrolli oma andmete üle ja luba neil oma andmetele ligi pääseda, neid muuta ja kustutada.
- API dokumentatsioon:
- Esita põhjalik ja hästi organiseeritud API dokumentatsioon, mis on kergesti mõistetav ja navigeeritav.
- Kasuta tööriistu nagu Swagger/OpenAPI interaktiivse API dokumentatsiooni genereerimiseks.
- Lisa koodinäiteid mitmes programmeerimiskeeles, et rahuldada mitmekesise publiku vajadusi.
- Tõlgi oma API dokumentatsioon mitmesse keelde, et jõuda laiema publikuni.
- Veakäsitlus:
- Esita spetsiifilised ja informatiivsed veateated. Väldi üldiseid veateateid nagu "Midagi läks valesti."
- Kasuta standardseid HTTP olekukoode vea tüübi märkimiseks (nt 400 halva päringu, 401 volitamata, 500 sisemise serverivea jaoks).
- Lisa veakoodid või identifikaatorid, mida saab kasutada probleemide jälgimiseks ja silumiseks.
- Logi vead serveri poolel silumiseks ja jälgimiseks.
- Määrade piiramine: Rakenda määrade piiramine (rate limiting), et kaitsta oma API-t kuritarvitamise eest ja tagada õiglane kasutus.
- Versioonimine: Kasuta API versioonimist, et lubada tagasiühilduvaid muudatusi ja vältida olemasolevate klientide rikkumist.
Järeldus
TypeScripti ja Expressi integreerimine parandab oluliselt teie taustarakenduste API-de töökindlust ja hooldatavust. Kasutades tüübiohutust marsruudikäitlejates ja vahevaras, saate vigu varakult arendusprotsessis tabada ja ehitada robustsemaid ja skaleeritavamaid rakendusi globaalsele publikule. Määratledes päringu- ja vastusetüüpe, tagate, et teie API järgib järjepidevat andmestruktuuri, vähendades käitusaja vigade tõenäosust. Ärge unustage järgida parimaid tavasid, nagu striktse režiimi lubamine, liideste ja tüübialiaste kasutamine ning ühiktestide kirjutamine, et maksimeerida TypeScripti eeliseid. Arvestage alati globaalsete teguritega, nagu lokaliseerimine, ajavööndid ja kultuuriline tundlikkus, et tagada teie API-de juurdepääsetavus ja kasutatavus kogu maailmas.